<template>
  <!-- 外层容器 -->
  <div class="patrol-management-container">
    <!-- 顶部区域 -->
    <div class="page-header">
      <div class="header-info">
        <h1>社区云巡检管理系统</h1>
        <p>实时监控巡更状态，高效管理巡更任务</p>
      </div>
      <el-select
          v-model="selectedCommunity"
          placeholder="请选择社区"
          @change="handleCommunityChange"
          class="community-select"
      >
        <el-option
            v-for="item in communityList"
            :key="item.id"
            :label="item.name"
            :value="item.id">
        </el-option>
      </el-select>
    </div>

    <!-- 核心仪表盘区域 -->
    <div class="dashboard">
      <!-- 左侧：ECharts 区域 -->
      <div class="dashboard-left">
        <div class="chart-card trend-chart">
          <h3 class="chart-title">今日巡检趋势</h3>
          <div id="patrolTrendChart" class="chart-container"></div>
        </div>
        <div class="chart-card exception-chart">
          <h3 class="chart-title">异常类型分布</h3>
          <div id="exceptionTypeChart" class="chart-container"></div>
        </div>
      </div>

      <!-- 中心可视化占位 -->
      <div class="dashboard-center">
        <div class="radar-placeholder">
          <div class="radar-glow"></div>
        </div>
      </div>

      <!-- 右侧：统计卡片 + 功能入口 -->
      <div class="dashboard-right">
        <!-- 统计卡片区 -->
        <div class="stats-panel">
          <!-- 第一行：三个卡片 -->
          <div class="stats-row">
            <el-card class="stat-card">
              <div class="stat-content">
                <div class="stat-info">
                  <p class="stat-label">今日巡更次数</p>
                  <h3 class="stat-value">{{ todayPatrolCount }}</h3>
                </div>
                <div class="stat-icon">
                  <el-icon><Clock /></el-icon>
                </div>
              </div>
              <div class="stat-trend">
        <span :class="todayTrendClass">
          {{ todayTrend }}{{ todayTrendPercent }}%
        </span>
                <span class="trend-desc">较昨日</span>
              </div>
            </el-card>

            <el-card class="stat-card">
              <div class="stat-content">
                <div class="stat-info">
                  <p class="stat-label">异常记录数</p>
                  <h3 class="stat-value">{{ exceptionCount }}</h3>
                </div>
                <div class="stat-icon warning">
                  <el-icon><WarningFilled /></el-icon>
                </div>
              </div>
              <div class="stat-trend">
        <span :class="exceptionTrendClass">
          {{ exceptionTrend }}{{ exceptionTrendPercent }}%
        </span>
                <span class="trend-desc">较昨日</span>
              </div>
            </el-card>

            <el-card class="stat-card">
              <div class="stat-content">
                <div class="stat-info">
                  <p class="stat-label">进行中计划</p>
                  <h3 class="stat-value">{{ ongoingPlanCount }}</h3>
                </div>
                <div class="stat-icon success">
                  <el-icon><RefreshLeft /></el-icon>
                </div>
              </div>
              <div class="stat-trend">
                <span>总计 {{ totalPlanCount }} 个计划</span>
              </div>
            </el-card>
          </div>

          <!-- 第二行：一个卡片 -->
          <div class="stats-row">
            <el-card class="stat-card full-width">
              <div class="stat-content">
                <div class="stat-info">
                  <p class="stat-label">有效巡更路线</p>
                  <h3 class="stat-value">{{ validRouteCount }}</h3>
                </div>
                <div class="stat-icon primary">
                  <el-icon><MapLocation /></el-icon>
                </div>
              </div>
              <div class="stat-trend">
                <span>包含 {{ totalPointCount }} 个点位</span>
              </div>
            </el-card>
          </div>
        </div>

        <!-- 功能入口区 -->
        <!-- 修改功能入口区 -->
        <div class="function-panel">
          <!-- 第一行：三个卡片 -->
          <div class="function-row">
            <el-card class="function-card" @click="$router.push('/category')">
              <div class="function-icon"><el-icon><Tickets /></el-icon></div>
              <h3 class="function-name">巡更分类管理</h3>
              <p class="function-desc">管理巡更点位的分类信息</p>
            </el-card>

            <el-card class="function-card" @click="$router.push('/point')">
              <div class="function-icon"><el-icon><LocationPointIcon /></el-icon></div>
              <h3 class="function-name">巡更点位管理</h3>
              <p class="function-desc">维护巡更点位的详细信息</p>
            </el-card>

            <el-card
                class="function-card"
                @click="$router.push('/route')"
            >
              <div class="function-icon">
                <el-icon><RouteMapIcon /></el-icon>
              </div>
              <h3 class="function-name">巡更路线管理</h3>
              <p class="function-desc">规划和管理巡更路线</p>
            </el-card>
          </div>

          <!-- 第二行：三个卡片 -->
          <div class="function-row">
            <el-card class="function-card" @click="$router.push('/plan')">
              <div class="function-icon"><el-icon><Calendar /></el-icon></div>
              <h3 class="function-name">巡更计划管理</h3>
              <p class="function-desc">创建和管理巡更计划</p>
            </el-card>

            <el-card class="function-card" @click="$router.push('/map')">
              <div class="function-icon"><el-icon><NavigationIcon /></el-icon></div>
              <h3 class="function-name">地图巡更</h3>
              <p class="function-desc">在地图上进行巡更操作</p>
            </el-card>

            <el-card class="function-card" @click="$router.push('/record')">
              <div class="function-icon"><el-icon><Document /></el-icon></div>
              <h3 class="function-name">巡更记录查询</h3>
              <p class="function-desc">查看和导出巡更记录</p>
            </el-card>
          </div>

          <!-- 第三行：两个卡片 -->
          <div class="function-row">
            <el-card class="function-card" @click="$router.push('/task')">
              <div class="function-icon"><el-icon><List /></el-icon></div>
              <h3 class="function-name">巡更任务管理</h3>
              <p class="function-desc">查看和管理所有巡更任务</p>
            </el-card>

            <!-- 预留位置，方便未来添加新组件 -->
            <el-card class="function-card" @click="$router.push('/analyze')">
              <div class="function-icon"><el-icon><List /></el-icon></div>
              <h3 class="function-name">巡更AI分析</h3>
              <p class="function-desc">AI分析所有巡更任务</p>
            </el-card>
          </div>
        </div>
      </div>
    </div>

    <!-- 底部异常记录区 -->
    <el-card class="recent-exceptions">
      <div slot="header" class="exception-header">
        <h3>最近异常记录</h3>
        <el-button @click="$router.push('/record')">查看全部</el-button>
      </div>
      <el-table
          :data="recentExceptions"
          border
          style="width: 100%;"
          v-if="recentExceptions.length > 0"
      >
        <el-table-column prop="pointName" label="巡更点位" width="180" />
        <el-table-column prop="updateTime" label="发现时间" width="180" />
        <el-table-column prop="photoUrls" label="异常照片" width="300">
          <template v-slot:default="scope">
            <div class="photo-preview">
              <div v-if="validPhotoUrls(scope.row.photoUrls).length === 0">
                <span class="text-gray-400">无照片</span>
              </div>
              <el-image
                  v-for="(url, idx) in validPhotoUrls(scope.row.photoUrls)"
                  :key="idx"
                  :src="url"
                  :preview-src-list="validPhotoUrls(scope.row.photoUrls)"
                  class="preview-img"
                  fit="cover"
                  v-if="idx < 2"
                  @error="handleImageError(url, $event)"
              >
                <template #placeholder>
                  <div class="image-placeholder">加载中...</div>
                </template>
                <template #error>
                  <div class="image-error">
                    <el-icon><PictureFilled /></el-icon>
                    <span>加载失败</span>
                  </div>
                </template>
              </el-image>
              <div
                  v-if="validPhotoUrls(scope.row.photoUrls).length > 2"
                  class="photo-count"
              >
                +{{ validPhotoUrls(scope.row.photoUrls).length - 2 }}
              </div>
            </div>
          </template>
        </el-table-column>
        <el-table-column prop="remark" label="异常说明" />
        <el-table-column label="操作" width="120">
          <template v-slot:default="scope">
            <el-button
                size="small"
                type="primary"
                @click="handleException(scope.row)"
            >
              处理
            </el-button>
          </template>
        </el-table-column>
      </el-table>
      <div v-else class="empty-exceptions">
        <p>暂无异常记录</p>
      </div>
    </el-card>
  </div>
</template>

<script>
import {ref, onMounted, onUnmounted, nextTick, getCurrentInstance, computed} from 'vue'
import { ElMessage, ElMessageBox } from 'element-plus'
import * as echarts from 'echarts'
import {
  Clock,
  WarningFilled,
  RefreshLeft,
  MapLocation,
  Tickets,
  Calendar,
  Document,
  MapLocation as RouteMapIcon,
  Location as LocationPointIcon,
  Compass as NavigationIcon,
  PictureFilled,
  List
} from '@element-plus/icons-vue'
import {getPatrolStats, getTodayPatrolTrend} from '../api/patrolManagement.js'
import { getRecentExceptions } from '../api/patrolRecord.js'
import server from "../utils/request.js";

export default {
  name: 'PatrolManagement',
  components: {
    PictureFilled,
    Clock,
    WarningFilled,
    RefreshLeft,
    MapLocation,
    Tickets,
    RouteMapIcon,
    Calendar,
    Document,
    LocationPointIcon,
    NavigationIcon,
    List
  },
  setup() {
    // 统计数据，保持原有逻辑
    const todayPatrolCount = ref(0)
    const todayTrend = ref('+')
    const todayTrendPercent = ref(0)
    const todayTrendClass = ref('increase')
    const communityList = ref([])
    const selectedCommunity = ref(null)
    const exceptionCount = ref(0)
    const exceptionTrend = ref('+')
    const exceptionTrendPercent = ref(0)
    const exceptionTrendClass = ref('increase')
    const ongoingPlanCount = ref(0)
    const totalPlanCount = ref(0)
    const validRouteCount = ref(0)
    const totalPointCount = ref(0)
    const recentExceptions = ref([])
    const isUnmounted = ref(false); // 新增标记
    const trendData = ref({
      times: [],
      statusCounts: {
        '未巡检': [],
        '巡检中': [],
        '已完成': []
      }
    });
    const isLoading = ref(true);
    const processPhotoUrls = (photoUrls) => {
      if (!photoUrls) return [];
      return photoUrls
          .split(',')
          .map(url => url.trim())
          .filter(url => url && url.startsWith('http'));
    }

    // 社区切换、加载数据逻辑，保持原有功能
    const handleCommunityChange = async (communityId) => {
      if (communityId) {
        ElMessage({ message: '切换社区...', type: 'success', duration: 800 });
        await loadStats();
        await loadRecentExceptions();
        await loadTodayTrend();
      }
    };
    // 将initCharts方法移到setup中
    const initCharts = () => {
      const patrolTrendChartDom = document.getElementById('patrolTrendChart');
      if (patrolTrendChartDom) {
        initPatrolTrendChart();
      }
      const exceptionTypeChartDom = document.getElementById('exceptionTypeChart');
      if (exceptionTypeChartDom) {
        initExceptionTypeChart();
      }
      console.log('初始化图表');
    };

    // 将initPatrolTrendChart和initExceptionTypeChart方法也移到setup中
    const initPatrolTrendChart = () => {
      const chartDom = document.getElementById('patrolTrendChart')
      if (!chartDom) return;

      const myChart = echarts.init(chartDom);
      console.log('patrolTrendChart 实例:', myChart);
      const option = {
        title: { text: '' },
        tooltip: { trigger: 'axis' },
        xAxis: {
          type: 'category',
          data: ['00:00', '04:00', '08:00', '12:00', '16:00', '20:00', '24:00']
        },
        yAxis: { type: 'value', name: '次数' },
        series: [
          {
            name: '巡更次数',
            data: [10, 20, 15, 30, 25, 22, 18],
            type: 'line',
            smooth: true,
            areaStyle: {}
          }
        ],
        color: ['#409eff']
      }
      myChart.setOption(option)
      // 监听窗口resize，保证响应式
      window.addEventListener('resize', () => myChart.resize())
    };
// 新增：加载今日巡更趋势数据
    const loadTodayTrend = async () => {
      if (!selectedCommunity.value) return; // 未选择社区则不请求
      try {
        let {data:data} = await getTodayPatrolTrend(selectedCommunity.value);
        console.log('今日巡更趋势数据:', data)
        if (data.code === 0) {
          trendData.value = data.data; // 保存后端返回数据
          updatePatrolTrendChart(); // 更新图表
        }
      } catch (error) {
        console.error('加载今日巡更趋势失败:', error);
      }
    };
    const initExceptionTypeChart = () => {
      const chartDom = document.getElementById('exceptionTypeChart')
      if (!chartDom) return;

      const myChart = echarts.init(chartDom);
      const option = {
        title: { text: '' },
        tooltip: { trigger: 'item' },
        legend: { orient: 'vertical', left: 'left' },
        series: [
          {
            name: '异常类型',
            type: 'pie',
            radius: ['40%', '70%'],
            data: [
              { value: 30, name: '点位异常' },
              { value: 20, name: '时间异常' },
              { value: 15, name: '照片异常' },
              { value: 35, name: '其他' }
            ],
            label: { show: false },
            labelLine: { show: false },
            emphasis: {
              label: { show: true, fontSize: '14', fontWeight: 'bold' }
            }
          }
        ],
        color: ['#f56c6c', '#67c23a', '#e6a23c', '#909399']
      }
      myChart.setOption(option)
      window.addEventListener('resize', () => myChart.resize())
    };
    const validPhotoUrls = (photoUrls) => {
      const result = (photoUrls || '')
          .split(',')
          .map(url => url.trim())
          .filter(url => url);
      console.log('validPhotoUrls result:', result);
      return result;
    };
    const handleImageError = (url, event) => {
      console.error('图片加载失败:', url, event);
    };
    const loadStats = async () => {
      if (!selectedCommunity.value) {
        ElMessage.warning('请先选择社区')
        return
      }
      try {
        let {data:data} = await getPatrolStats(selectedCommunity.value)
        console.log('获取统计数据成功:', data)
        if (data.code === 0) {
          const stats = data.data;
          console.log('后端返回的统计数据:', stats);
          todayPatrolCount.value = stats.todayPatrolCount || 0
          todayTrend.value = stats.todayPatrolTrend >= 0 ? '+' : ''
          todayTrendPercent.value = Math.abs(stats.todayPatrolTrend) || 0
          todayTrendClass.value = stats.todayPatrolTrend >= 0 ? 'increase' : 'decrease'
          exceptionCount.value = stats.exceptionCount || 0
          exceptionTrend.value = stats.exceptionTrend >= 0 ? '+' : ''
          exceptionTrendPercent.value = Math.abs(stats.exceptionTrend) || 0
          exceptionTrendClass.value = stats.exceptionTrend >= 0 ? 'increase' : 'decrease'
          ongoingPlanCount.value = stats.ongoingPlanCount || 0
          totalPlanCount.value = stats.totalPlanCount || 0
          validRouteCount.value = stats.validRouteCount || 0
          totalPointCount.value = stats.totalPointCount || 0
          // 确保DOM已经渲染完成后再初始化图表
          await nextTick();
          updatePatrolTrendChart(stats);  // 使用实际数据更新图表
          updateExceptionTypeChart(stats);  // 使用实际数据更新图表
        } else {
          ElMessage.error(data.message || '加载统计数据失败')
        }
      } catch (error) {
        ElMessage.error('网络错误，请稍后重试')
        console.error('加载统计数据失败:', error)
        // 即使发生错误，也初始化图表（使用默认数据）
        await nextTick();
        initPatrolTrendChart();
        initExceptionTypeChart();
      }
    }
    // 更新巡更趋势图表
    const updatePatrolTrendChart = () => {
      if (isUnmounted.value) return;
      const chartDom = document.getElementById('patrolTrendChart');
      if (!chartDom) return;

      // 获取或创建图表实例
      const myChart = echarts.init(chartDom);

      // 从趋势数据中提取图表所需参数
      const { times, statusCounts } = trendData.value;

      // 图表配置（多系列折线图，分别对应三种状态）
      const option = {
        tooltip: {
          trigger: 'axis',
          axisPointer: { type: 'shadow' }
        },
        legend: {
          data: ['未巡检', '巡检中', '已完成'], // 图例与后端状态名一致
          top: 0,
          selected: {
            '未巡检': true,
            '巡检中': true,
            '已完成': true
          },
          textStyle: {
            // 初始颜色白色
            color: '#ffffff'
          },
        },
        grid: {
          left: '3%',
          right: '4%',
          bottom: '3%',
          containLabel: true
        },
        xAxis: {
          type: 'category',
          data: times.length > 0 ? times : Array.from({length: 24}, (_, i) => `${i.toString().padStart(2, '0')}:00`)
        },
        yAxis: {
          type: 'value',
          name: '路线数量',
          min: 0 // 确保Y轴从0开始
        },
        series: [
          {
            name: '未巡检',
            type: 'line',
            data: statusCounts['未巡检'] || new Array(24).fill(0),
            smooth: true,
            lineStyle: { color: '#f56c6c' }, // 红色
            areaStyle: { color: new echarts.graphic.LinearGradient(0, 0, 0, 1, [{
                offset: 0, color: 'rgba(245, 108, 108, 0.3)'
              }, { offset: 1, color: 'rgba(245, 108, 108, 0)' }])}
          },
          {
            name: '巡检中',
            type: 'line',
            data: statusCounts['巡检中'] || new Array(24).fill(0),
            smooth: true,
            lineStyle: { color: '#e6a23c' }, // 橙色
            areaStyle: { color: new echarts.graphic.LinearGradient(0, 0, 0, 1, [{
                offset: 0, color: 'rgba(230, 162, 60, 0.3)'
              }, { offset: 1, color: 'rgba(230, 162, 60, 0)' }])}
          },
          {
            name: '已完成',
            type: 'line',
            data: statusCounts['已完成'] || new Array(24).fill(0),
            smooth: true,
            lineStyle: { color: '#67c23a' }, // 绿色
            areaStyle: { color: new echarts.graphic.LinearGradient(0, 0, 0, 1, [{
                offset: 0, color: 'rgba(103, 194, 58, 0.3)'
              }, { offset: 1, color: 'rgba(103, 194, 58, 0)' }])}
          }
        ]
      };

      myChart.setOption(option);
      // 监听窗口大小变化
      window.addEventListener('resize', () => myChart.resize());
    };

// 更新异常类型图表
    const updateExceptionTypeChart = (stats) => {
      const chartDom = document.getElementById('exceptionTypeChart');
      if (!chartDom) return;

      const myChart = echarts.getInstanceByDom(chartDom) || echarts.init(chartDom);

      // 关键修复：从 stats.exceptionTypes 获取数据（对应后端的remark统计结果）
      const validData = (stats.exceptionTypes || []).filter(item => {
        return item.name && item.value > 0; // 过滤无效数据
      });

      const option = {
        series: [{
          name: '异常类型',
          type: 'pie',
          radius: ['40%', '70%'],
          data: validData.length > 0 ? validData : [
            { name: '无异常记录', value: 1 } // 空数据时显示默认项
          ],
          label: { show: false },
          labelLine: { show: false },
          emphasis: {
            label: { show: true, fontSize: '14', fontWeight: 'bold' }
          }
        }]
      };
      myChart.setOption(option);
    };



    const loadCommunityList = async () => {
      try {
        let {data:data} = await server({
          url: '/community/list',
          method: 'GET'
        })
        if (data.code === 0) {
          communityList.value = data.data || []
          if (communityList.value.length > 0) {
            selectedCommunity.value = communityList.value [0].id
          }
        } else {
          ElMessage.error (' 加载社区列表失败 ')
        }
      } catch (error) {
        ElMessage.error (' 加载社区列表时发生网络错误 ')
        console.error (' 加载社区列表失败:', error)
      }
    }
    const loadRecentExceptions = async () => {
      if (!selectedCommunity.value) {
        ElMessage.warning (' 请先选择社区 ')
        return
      }
      try {
        let {data:data} = await getRecentExceptions (selectedCommunity.value, 5);
        if (data.code === 0) {
          recentExceptions.value = data.data || [];
        } else {
          ElMessage.error (data.message || ' 加载异常记录失败 ');
        }
      } catch (error) {
        ElMessage.error (' 网络错误，请稍后重试 ');
        console.error (' 加载异常记录失败:', error);
      }
    }
    const handleException = (record) => {
      ElMessageBox.prompt(
          `请输入对 "${record.pointName}" 异常的处理结果`,
          // ' 处理异常 ',
          {
            confirmButtonText: ' 确定 ',
            cancelButtonText: ' 取消 ',
            inputType: 'textarea'
          }
      ).then (({value}) => {
        ElMessage.success (' 处理结果已提交 ')
        loadRecentExceptions ()
      }).catch (() => {})
    }
// 新增：组件挂载时初始化图表
    onMounted(async () => {
      await loadCommunityList();
      if (selectedCommunity.value) {
        await loadStats(); // 加载其他统计数据
        await loadRecentExceptions(); // 加载最近异常
        await loadTodayTrend(); // 新增：加载今日巡更趋势
      }
    });


// 新增：组件卸载时销毁图表，避免内存泄漏
    onUnmounted(() => {
      isUnmounted.value = true; // 卸载时标记
      // 1. 销毁图表实例（原有逻辑）
      const destroyChart = (domId) => {
        const chartDom = document.getElementById(domId);
        if (chartDom) {
          const chartInstance = echarts.getInstanceByDom(chartDom);
          if (chartInstance) {
            chartInstance.dispose();
            // 额外移除 resize 监听（关键！防止残留监听）
            window.removeEventListener('resize', chartInstance.resize);
          }
        }
      };
      destroyChart('patrolTrendChart');
      destroyChart('exceptionTypeChart');
    });


    return {
      todayPatrolCount,
      todayTrend,
      todayTrendPercent,
      todayTrendClass,
      exceptionCount,
      exceptionTrend,
      exceptionTrendPercent,
      exceptionTrendClass,
      ongoingPlanCount,
      totalPlanCount,
      validRouteCount,
      totalPointCount,
      recentExceptions,
      handleException,
      communityList,
      selectedCommunity,
      handleCommunityChange,
      validPhotoUrls,
      handleImageError,
      initCharts
    }
  }
}
</script>
<style scoped>
/* 基础样式 */
.patrol-management-container {
  padding: 20px;
  min-height: 100vh;
  color: #e2e8f0;
  background: linear-gradient(135deg, #0f172a 0%, #0b111e 100%);
  font-family: "Microsoft YaHei", sans-serif;
}

/* 顶部标题区 */
.page-header {
  display: flex;
  justify-content: space-between;
  align-items: flex-end;
  margin-bottom: 30px;
  padding-bottom: 10px;
  border-bottom: 1px solid rgba(255,255,255,0.1);
}
.header-info h1 {
  font-size: 28px;
  color: #f8fafc;
  margin: 0;
  text-shadow: 0 0 10px rgba(255,255,255,0.2);
}
.header-info p {
  color: #94a3b8;
  font-size: 14px;
  margin: 5px 0 0;
  opacity: 0.9;
}

/* 社区选择器 */
.community-select {
  width: 200px;
  &:deep(.el-input__inner) {
    background-color: rgba(255,255,255,0.05);
    border: 1px solid rgba(255,255,255,0.2);
    color: #e2e8f0;
    &:hover {
      box-shadow: 0 0 10px rgba(64,158,255,0.3);
    }
  }
}

/* 核心仪表盘布局 */
.dashboard {
  display: flex;
  gap: 20px;
  margin-bottom: 30px;
}

/* 左侧可视化区：占比 45% */
.dashboard-left {
  flex: 0 0 45%;
  display: flex;
  flex-direction: column;
  gap: 15px;
}

/* 中心雷达图占位：缩小尺寸 */
.dashboard-center {
  flex: 0 0 200px;
  display: flex;
  justify-content: center;
  align-items: center;
  position: relative;
  &::before {
    content: "";
    position: absolute;
    width: 100%;
    height: 100%;
    border: 1px solid transparent;
    border-radius: 50%;
    background: linear-gradient(45deg, #409eff, #67c23a);
    background-clip: padding-box;
    z-index: 1;
    opacity: 0.2;
    animation: rotate 10s linear infinite;
  }
  &::after {
    content: "";
    position: absolute;
    width: 90%;
    height: 90%;
    border-radius: 50%;
    background: radial-gradient(circle at center, rgba(64,158,255,0.1) 0%, transparent 70%);
  }
}
.radar-placeholder {
  width: 180px;
  height: 180px;
  background: radial-gradient(circle, rgba(0,0,0,0.5) 0%, transparent 100%);
  border-radius: 50%;
  display: flex;
  justify-content: center;
  align-items: center;
  position: relative;
  z-index: 2;
  box-shadow: 0 0 20px rgba(64,158,255,0.2);
  &::before {
    content: "";
    position: absolute;
    width: 120%;
    height: 120%;
    border: 1px dashed rgba(64,158,255,0.3);
    border-radius: 50%;
    animation: pulse 3s infinite;
  }
}
.radar-glow {
  width: 100%;
  height: 100%;
  border-radius: 50%;
  background: radial-gradient(circle, rgba(64,158,255,0.2) 0%, transparent 70%);
  filter: blur(15px);
  opacity: 0.5;
}

/* 右侧统计/功能区：占比 35%（缩小） */
.dashboard-right {
  flex: 0 0 35%;
  display: flex;
  flex-direction: column;
  gap: 20px;
}

/* 图表卡片 */
.chart-card {
  background-color: rgba(255,255,255,0.05) !important;
  border: 1px solid rgba(255,255,255,0.1) !important;
  border-radius: 10px;
  padding: 15px;
  box-shadow: 0 0 15px rgba(0,0,0,0.3);
  &:hover {
    box-shadow: 0 0 20px rgba(64,158,255,0.2);
  }
}
.chart-title {
  margin: 0 0 10px;
  font-size: 16px;
  color: #f8fafc;
  text-shadow: 0 0 5px rgba(255,255,255,0.3);
}
.chart-container {
  width: 100%;
  height: 280px;
  position: relative;
  z-index: 1;
}

/* 统计卡片区域 */
.stats-panel {
  display: flex;
  flex-direction: column;
  gap: 10px;
}
.chart-spacer {
  height: 25px;
}
.stats-row {
  display: flex;
  gap: 10px;
}
.full-width {
  flex: 1 1 100%;
}
.stat-card {
  background-color: rgba(255,255,255,0.05) !important;
  border: 1px solid rgba(255,255,255,0.1) !important;
  border-radius: 8px;
  padding: 12px;
  flex: 1;
  transition: all 0.3s;
  overflow: hidden;
  &::before {
    content: "";
    position: absolute;
    top: 0;
    left: 0;
    width: 100%;
    height: 1px;
    background: linear-gradient(90deg, transparent, #409eff, transparent);
    opacity: 0;
    transition: opacity 0.3s;
  }
  &:hover {
    transform: translateY(-2px);
    box-shadow: 0 5px 10px rgba(0,0,0,0.3);
    &::before {
      opacity: 1;
    }
  }
}
.stat-content {
  display: flex;
  justify-content: space-between;
  align-items: center;
}
.stat-info .stat-label {
  color: #94a3b8;
  font-size: 12px;
  margin: 0 0 3px;
}
.stat-info .stat-value {
  font-size: 22px;
  font-weight: bold;
  margin: 0;
  color: #f8fafc;
  text-shadow: 0 0 5px rgba(255,255,255,0.1);
}
.stat-icon {
  width: 35px;
  height: 35px;
  border-radius: 6px;
  display: flex;
  justify-content: center;
  align-items: center;
  background-color: rgba(64,158,255,0.1);
  color: #409eff;
  font-size: 18px;
}
.stat-icon.warning {
  background-color: rgba(245,108,108,0.1);
  color: #f56c6c;
}
.stat-icon.success {
  background-color: rgba(103,194,58,0.1);
  color: #67c23a;
}
.stat-icon.primary {
  background-color: rgba(14,165,233,0.1);
  color: #0ea5e9;
}
.stat-trend {
  margin-top: 8px;
  font-size: 11px;
  color: #94a3b8;
  display: flex;
  align-items: center;
  gap: 5px;
}
.increase {
  color: #f56c6c;
}
.decrease {
  color: #67c23a;
}

/* 功能入口区：改为两列 */
.function-panel {
  display: flex;
  flex-direction: column;
  gap: 10px;
}
.function-row {
  display: flex;
  gap: 10px;
}
.placeholder {
  background-color: rgba(255,255,255,0.02) !important;
  cursor: not-allowed;
  opacity: 0.5;
}

.function-card {
  background-color: rgba(255,255,255,0.05) !important;
  border: 1px solid rgba(255,255,255,0.1) !important;
  border-radius: 8px;
  padding: 12px;
  flex: 1;
  cursor: pointer;
  transition: all 0.3s;
  &:hover {
    transform: translateY(-2px) scale(1.01);
    box-shadow: 0 3px 10px rgba(64,158,255,0.2);
    border-color: rgba(64,158,255,0.3) !important;
  }
}
.function-icon {
  width: 35px;
  height: 35px;
  border-radius: 6px;
  display: flex;
  justify-content: center;
  align-items: center;
  background-color: rgba(64,158,255,0.1);
  color: #409eff;
  margin-bottom: 8px;
}
.function-name {
  font-size: 14px;
  margin: 0 0 3px;
  color: #f8fafc;
}
.function-desc {
  font-size: 11px;
  color: #94a3b8;
  margin: 0;
  opacity: 0.8;
}

/* 底部异常记录区 */
.recent-exceptions {
  background-color: rgba(255,255,255,0.05) !important;
  border: 1px solid rgba(255,255,255,0.1) !important;
  border-radius: 10px;
  margin-top: 20px;
  overflow: hidden;
}
.exception-header {
  display: flex;
  justify-content: space-between;
  align-items: center;
  padding: 12px 15px;
  border-bottom: 1px solid rgba(255,255,255,0.1);
}
.exception-header h3 {
  margin: 0;
  color: #f8fafc;
  font-size: 16px;
}
/* 表格样式 */
:deep(.el-table) {
  background-color: transparent !important;
  color: #e2e8f0;
  &::before {
    background-color: rgba(255,255,255,0.1) !important;
  }
}
:deep(.el-table th) {
  background-color: rgba(255,255,255,0.05) !important;
  color: #94a3b8;
  border-bottom: 1px solid rgba(255,255,255,0.1) !important;
  font-size: 13px;
}
:deep(.el-table tr) {
  background-color: transparent !important;
}
:deep(.el-table tr:hover > td) {
  background-color: rgba(64,158,255,0.05) !important;
}
:deep(.el-table td) {
  border-bottom: 1px solid rgba(255,255,255,0.05) !important;
  font-size: 13px;
}

/* 照片预览区 */
.photo-preview {
  display: flex;
  align-items: center;
  gap: 3px;
  width: 100%;
  height: 35px;
}
.preview-img {
  width: 35px;
  height: 35px;
  border-radius: 3px;
  cursor: pointer;
  object-fit: cover;
  border: 1px solid rgba(255,255,255,0.1);
}
.photo-count {
  width: 35px;
  height: 35px;
  background-color: rgba(255,255,255,0.05);
  border-radius: 3px;
  display: flex;
  align-items: center;
  justify-content: center;
  font-size: 11px;
  color: #94a3b8;
  border: 1px solid rgba(255,255,255,0.1);
}
.empty-exceptions {
  text-align: center;
  padding: 40px 0;
  color: #94a3b8;
  font-size: 13px;
}

/* 按钮样式 */
:deep(.el-button) {
  background-color: rgba(64,158,255,0.2) !important;
  border-color: rgba(64,158,255,0.4) !important;
  color: #409eff !important;
  transition: all 0.3s;
  font-size: 13px !important;
  padding: 7px 15px !important;
  &:hover {
    background-color: rgba(64,158,255,0.3) !important;
    box-shadow: 0 0 8px rgba(64,158,255,0.3) !important;
  }
}

/* 动画效果 */
@keyframes rotate {
  0% { transform: rotate(0deg); }
  100% { transform: rotate(360deg); }
}
@keyframes pulse {
  0% { transform: scale(1); opacity: 0.5; }
  50% { transform: scale(1.1); opacity: 0.8; }
  100% { transform: scale(1); opacity: 0.5; }
}

/* 响应式调整 */
@media (max-width: 1024px) {
  .dashboard {
    flex-wrap: wrap;
  }
  .dashboard-left, .dashboard-right {
    flex: 0 0 100%;
  }
  .dashboard-center {
    order: -1;
    margin: 20px 0;
  }
}
@media (max-width: 768px) {
  .function-panel {
    grid-template-columns: 1fr;
  }
  .header-info h1 {
    font-size: 22px;
  }
  .dashboard-center {
    flex: 0 0 160px;
  }
  .radar-placeholder {
    width: 160px;
    height: 160px;
  }
  .stats-row {
    flex-direction: column;
  }
  .function-row {
    flex-direction: column;
  }
}
</style>